package com.itboye.api.controller;

import com.itboye.api.helper.WebFileHelper;
import com.itboye.mybatis.enumtype.DataStatus;
import com.itboye.mybatis.enumtype.FileType;
import com.itboye.mybatis.model.UserPictureModel;
import com.itboye.services.ucenter.interfaces.IMemberService;
import com.itboye.services.utils.interfaces.IUserPictureService;
import com.itboye.system.bean.ByResultBean;
import com.itboye.system.crypt.JsonCrypt;
import com.itboye.system.crypt.MD5Crypt;
import com.itboye.system.crypt.Sha1Crypt;
import com.itboye.system.exception.ByServiceException;
import com.itboye.system.helper.ByConfigHelper;
import com.itboye.system.helper.ByConsoleHelper;
import com.itboye.system.helper.ByDateHelper;
import com.itboye.system.helper.ByUniqueIDHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;

/**
 * FileController.java
 * Created on  2016/7/30 16:40
 * 版本       修改时间          作者      修改内容
 * V1.0.1    2016/7/30      hebidu    初始版本
 * TODO:
 *   1. 图片缩略图
 * Copyright (c) 2013 杭州博也网络科技有限公司 版权所有
 * HANGZHOU BOYE TECHNOLOGY CO.,LTD. All Rights Reserved.
 */
@Controller
public class FileCurlController {

    private static final Logger logger = LogManager.getLogger(FileController.class.toString());

    @Resource
    private IUserPictureService userPictureService;

    @Resource
    private IMemberService memberService;

    private UserPictureModel userPictureModel;
    private String notifyId;

    public String getNotifyId() {
        if(this.notifyId == null || this.notifyId.length() == 0){
            notifyId = ByDateHelper.getCurrentTimeStamp().toString();
        }
        return notifyId;
    }

    private UserPictureModel getUserPictureModel(){
        UserPictureModel userPictureModel = new UserPictureModel();
        int createTime = ByDateHelper.getCurrentTimeStamp().intValue();
        userPictureModel.setStatus(DataStatus.NORMAL);
        userPictureModel.setCreateTime(createTime);
        return userPictureModel;
    }

    /**
     * 文件上传接口,目前暂支持图片类型上传
     * @param request
     * @param response
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    @RequestMapping(value = "/file/curl_upload",produces = "application/json;charset=UTF-8")
    @ResponseBody
    public String curl_upload(HttpServletRequest request, HttpServletResponse response) throws IOException, NoSuchAlgorithmException {
        int maxSize = ByConfigHelper.getInstance().getUploadFileMaxSize();
        int size = request.getContentLength();

        if(maxSize < size){
            return  fail("文件大小太大(最大1M)");
        }

        String filePath = "";

        ByConsoleHelper.info("文件保存路径=",logger);

        String tmp = request.getParameter("uid");

        if(tmp == null || tmp.length() == 0){
            tmp = "0";
        }

        String type = request.getParameter("type");
        if(type == null){
            type = "";
        }

        String originName = request.getParameter("fname");

        if(originName == null){
            return  fail("缺少图片名称");
        }

        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        // 判断 request 是否有文件上传,即多部分请求
        if (multipartResolver.isMultipart(request)) {
            // 转换成多部分request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            // 取得request中的所有文件名
            Iterator<String> iterator = multiRequest.getFileNames();

            while (iterator.hasNext()) {
                // 取得上传文件
                MultipartFile f = multiRequest.getFile(iterator.next());
                if (f != null) {
//                    ByResultBean bean = checkFile(f);
//                    if(!bean.isSuccess()){
//                        return fail(bean.getMsg());
//                    }

                    userPictureModel = getUserPictureModel();
                    userPictureModel.setUid(Integer.parseInt(tmp));
                    userPictureModel.setType(type);
                    try {
                        UserPictureModel model = saveFile(filePath,originName, f, size);
                        aopType(model);
                        if(model != null){
                            return success(model);
                        }
                    }catch (ByServiceException e){
                        ByConsoleHelper.info(e.getLocalizedMessage(),logger);
                        return fail("上传失败(-2)");
                    }
                }
            }
        }

        return fail("上传失败!");
    }

    private void aopType(UserPictureModel model) throws ByServiceException{
        System.out.println(JsonCrypt.toJson(model));
        if(model.getType().equals(FileType.Avatar)){
            //头像类型拦截,特殊处理
            HashMap<String,String> params = new HashMap<String, String>();
            params.put("uid","" + model.getUid());
            params.put("head","" + model.getId());
            memberService.update(params);
        }else if(model.getType().equals(FileType.Business_License)){
            //执照拦截,上传执照后自动认证通过
            HashMap<String,String> params = new HashMap<String, String>();
            params.put("isAuthE","1");
            params.put("uid","" + model.getUid());
            memberService.update(params);
        }

    }

    /**
     * 检验文件是否合法
     * @param file
     * @return
     */
//    private ByResultBean checkFile(MultipartFile file){
//        //原文件名
//        String oriFilename = file.getOriginalFilename();
//        //文件后缀
//        String ext = "";
//
//        if(oriFilename.lastIndexOf(".") > -1) {
//            ext = oriFilename.substring(oriFilename.lastIndexOf(".")+1).toLowerCase();
//        }
//
//        if(ext.trim().length() == 0){
//            return ByResultBean.fail("上传文件后缀名不许为空!");
//        }
//
//        String[] allowExts = ByConfigHelper.getInstance().getUploadFileAllowExts();
////        System.out.println(allowExts.length);
//        if(allowExts != null){
//            boolean isAllowExt = false;
//            for (int i=0;i<allowExts.length;i++){
//                if(allowExts[i].equals(ext)){
//                    isAllowExt = true;
//                }
//            }
//
//            if(!isAllowExt){
//                return ByResultBean.fail("非法的文件类型");
//            }
//        }
//
//        return ByResultBean.success("合法文件");
//    }


    private UserPictureModel saveFile(String filePath,String oriFilename, MultipartFile uploadFile ,int size) throws ByServiceException, NoSuchAlgorithmException, IOException {
        String path = ByConfigHelper.getInstance().getUploadFilePath();
        filePath = filePath + path;
        //文件后缀
        String ext = "";
        if(oriFilename.lastIndexOf(".") > -1) {
            ext = oriFilename.substring(oriFilename.lastIndexOf(".")).toLowerCase();
        }

        //保存的文件名
        String saveFileName = generateFileName(oriFilename);
        //保存的路径,相对于filePath
        String datePath = generateDatePath();
        String url = ByConfigHelper.getInstance().getImgSiteUrl();
        url = url + datePath + saveFileName + ext;
        // 定义上传路径
        String realFilePath = filePath + datePath +  saveFileName + ext;
        File file = new File(realFilePath);

        if(!file.getParentFile().exists()){

            ByConsoleHelper.debug("[File]目标文件所在目录不存在，准备创建它"+file.getParentFile(),logger);
            if(!file.getParentFile().mkdirs()) {
                ByConsoleHelper.info("创建目标文件所在目录失败！",logger);
            }
        }

        //实际保存文件
        ByteBuffer byteBuffer = ByteBuffer.wrap(uploadFile.getBytes());
        String md5 = MD5Crypt.getMd5FromBytes(byteBuffer);
        byteBuffer = ByteBuffer.wrap(uploadFile.getBytes());
        String sha1 = Sha1Crypt.getSha1FromBytes(byteBuffer);

        String fileName = generateFileName(oriFilename);
        userPictureModel.setSaveName(fileName+ext);
        userPictureModel.setOriName(oriFilename);
        userPictureModel.setSize(size);
        userPictureModel.setExt(ext.trim());
        userPictureModel.setPath(datePath +  saveFileName + ext);
        userPictureModel.setUrl(url);
        userPictureModel.setMd5(md5);
        userPictureModel.setSha1(sha1);
        userPictureModel.setImgUrl(url);


        HashMap<String,String> params = new HashMap<String, String>();
        params.put("md5",md5);
        params.put("sha1",sha1);
        // 检查是否已存在该文件
        UserPictureModel pictureModel = userPictureService.getInfoBy(params);

        if(pictureModel != null){
            userPictureModel.setCreateTime(ByDateHelper.getCurrentTimeStamp().intValue());
            userPictureModel.setImgUrl(pictureModel.getImgUrl());
            userPictureModel.setMd5(pictureModel.getMd5());
            userPictureModel.setSha1(pictureModel.getSha1());
            userPictureModel.setUrl(pictureModel.getUrl());
            userPictureModel.setPath(pictureModel.getPath());
            userPictureModel.setExt(pictureModel.getExt());
            userPictureModel.setSaveName(pictureModel.getSaveName());
            userPictureModel.setOriName(pictureModel.getOriName());
            userPictureModel.setSize(pictureModel.getSize());
        }

        int effectRows = userPictureService.insert(userPictureModel);
        if(effectRows == 0){
            ByConsoleHelper.info("文件信息插入数据库失败",logger);
        }

        try {
            if(pictureModel == null){
                uploadFile.transferTo(file);
            }
        }catch (IOException e){
            e.printStackTrace();
            ByConsoleHelper.debug("上传文件出错",logger);
        }

        return userPictureModel;
    }



    /**
     *
     * 生成新的文件名
     * @param fileName 旧的文件名
     * @return
     * @throws UnsupportedEncodingException
     * @throws NoSuchAlgorithmException
     * @throws SocketException
     * @throws UnknownHostException
     */
    private String generateFileName(String fileName) throws UnsupportedEncodingException, NoSuchAlgorithmException, SocketException, UnknownHostException {
        String salt = Integer.toHexString(fileName.hashCode());
        return ByUniqueIDHelper.generate(salt,"_");
    }

    /**
     * 生成文件保存路径
     * @return
     */
    private String generateDatePath(){

        Date date = new Date();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat ("yyyy/MM/dd/");

        String strDate = simpleDateFormat.format(date);

        return strDate;

    }


    private String fail(String failMsg){

        HashMap<String,String> result = new HashMap<String, String>();

        result.put("code","-1");
        result.put("data",failMsg);
        result.put("notify_id",getNotifyId());

        return JsonCrypt.toJson(result);
    }

    private String success(Object data){

        HashMap<String,Object> result = new HashMap<String, Object>();

        result.put("code","0");
        result.put("data",data);
        result.put("notify_id",getNotifyId());

        return JsonCrypt.toJson(result);
    }

}
